package com.xy.biz.base.support.bizcode;

import com.xy.biz.base.domain.bo.BizCodeBO;
import com.xy.lang.util.CalendarUtils;
import org.springframework.stereotype.Service;

import static com.xy.biz.base.support.bizcode.BizCodeGenerator.ALGORITHM_SERVICE_PREFIX;
import static com.xy.biz.base.support.bizcode.BizCodeGenerator.ALGORITHM_SNOWFLAKE;

@Service(ALGORITHM_SERVICE_PREFIX + ALGORITHM_SNOWFLAKE)
public class SnowflakeBizCodeGenerator implements BizCodeGenerator {

    private final static long timestampOffset = 18500; // 2020-08-26

    @Override
    public long getTimestamp() {
        return (CalendarUtils.toEpochSecond() / 86400) - timestampOffset;
    }

    @Override
    public String generate(BizCodeBO bizCodeBO, int nextValue) {
        long timestamp = bizCodeBO.getTimestamp();
        long tenantId = (null == bizCodeBO.getTenantId()) ? 0 : bizCodeBO.getTenantId();
        //the max count of tenant: 255, the max count per day of biz code: 65535
        long value = timestamp << 24 | tenantId << 16 | (long)nextValue;
        return String.valueOf(value);
    }

    public static void main(String[] args) {
        System.out.println((CalendarUtils.toEpochSecond() - 86401) / 86400);
        System.out.println((CalendarUtils.toEpochSecond() - 86401) / 86400 / 365);
        System.out.println(CalendarUtils.toEpochSecond() / 86400);
        System.out.println(CalendarUtils.toEpochSecond() / 86400 / 365);
        System.out.println(1 << 8);
        System.out.println(1 << 16);
        System.out.println("-----------");

        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 0 << 16 | 1);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 1 << 16 | 1);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 2 << 16 | 1);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 255 << 16 | 1);
        System.out.println("-----------");

        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 0 << 16 | 10);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 1 << 16 | 10);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 2 << 16 | 10);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 255 << 16 | 10);
        System.out.println("-----------");

        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 0 << 16 | 65535);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 1 << 16 | 65535);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 2 << 16 | 65535);
        System.out.println((CalendarUtils.toEpochSecond() / 86400) << 24 | 255 << 16 | 65535);
        System.out.println("-----------");

        System.out.println(1 << 24 | 0 << 16 | 65535);
        System.out.println(1 << 24 | 1 << 16 | 65535);
        System.out.println(1 << 24 | 2 << 16 | 65535);
        System.out.println(1 << 24 | 255 << 16 | 65535);
        System.out.println("-----------");
    }

}
